package com.slz3.business.frame.steward;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.MultiValueMap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class PageableSteward {

    private static final String PAGE = "page";
    private static final String SIZE = "size";
    private static final String ORDERS = "orders";
    private static final String SEPARATE_ORDER = ",";
    private static final String SEPARATE_ORDER_TYPE = "-";
    private static final String DESC = "desc";
    private static final String ASC = "asc";
    private static final String EXCEPTION_PAGE$SIZE = "page or size is null";

    public static Pageable extract(MultiValueMap<String, String> params) {
        Pageable pageable;
        String pageStr = params.getFirst(PAGE);
        String sizeStr = params.getFirst(SIZE);
        Integer page;
        Integer size;
        Sort sort = null;
        if (pageStr == null || sizeStr == null) {
            throw new RuntimeException(EXCEPTION_PAGE$SIZE);
        } else {
            page = Integer.valueOf(pageStr);
            size = Integer.valueOf(sizeStr);
        }
        String orders = params.getFirst(ORDERS);
        if (orders != null) {
            List<Sort.Order> orderList = new ArrayList<>();
            Arrays.stream(orders.split(SEPARATE_ORDER)).forEach(item -> {
                String[] orderInfo = item.split(SEPARATE_ORDER_TYPE);
                String fieldName = orderInfo[0];
                String orderType = orderInfo[1];
                switch (orderType) {
                    case DESC:
                        orderList.add(Sort.Order.desc(fieldName));
                        break;
                    case ASC:
                        orderList.add(Sort.Order.asc(fieldName));
                        break;
                }
            });
            sort = Sort.by(orderList);
        }
        pageable = sort == null ? PageRequest.of(page, size) : PageRequest.of(page, size, sort);
        return pageable;
    }

}
